/**
 * 
 */
package com.p2p.front.service.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.p2p.front.dal.dao.UserInfoAuthDao;
import com.p2p.front.dal.model.AuthValue;
import com.p2p.front.dal.model.UserInfoAuth;
import com.p2p.front.dal.model.UserInfoAuth.AuthStatus;
import com.p2p.front.service.UserInfoAuthService;
import com.p2p.user.enums.UserAuthName;

/**
 * @author ruiqi
 *
 */

@Service("userInfoAuthService")
public class UserInfoAuthServiceImpl implements UserInfoAuthService {

	private final Logger logger = LoggerFactory
			.getLogger(UserInfoAuthServiceImpl.class);

	private char defaultCharacter = '0';

	private int defaultMaxLength = 100;

	@Resource
	private UserInfoAuthDao userInfoAuthDao;

	@Override
	@Transactional
	public void saveEmailAuth(String uid) {
		List<AuthValue> authValueList = new ArrayList<AuthValue>();
		AuthValue emailAuth = new AuthValue(UserAuthName.AUTH_EMAIL,
				AuthStatus.AUTHSUCCESS.getAuthStatus());
		authValueList.add(emailAuth);
		this.saveAuthByAuthValueList(uid, authValueList);
	}

	@Override
	@Transactional
	public void saveAuthByValueMap(String userId,
			TreeMap<Integer, Character> authMap) {
		UserInfoAuth userInfoAuth = userInfoAuthDao.selectForUpdate(userId);
		if (userInfoAuth == null) {
			userInfoAuth = this.initAuth(userId, defaultMaxLength);
		}
		StringBuilder authValue = new StringBuilder(userInfoAuth.getAuthValue());
		int valueLength = authValue.length();
		for (Map.Entry<Integer, Character> entry : authMap.entrySet()) {
			Integer key = entry.getKey();
			Character value = entry.getValue();
			if (key > valueLength) {
				String addValue = getDefaultString(key - valueLength);
				authValue.append(addValue);
				valueLength = authValue.length();
			}
			authValue.replace(key - 1, key, value.toString());
		}
		userInfoAuth.setAuthValue(authValue.toString());
		userInfoAuthDao.save(userInfoAuth);
	}

	@Override
	public Map<Integer, Character> getAuthNameKeyList(String userId,
			Collection<Integer> authKeyList) {
		UserInfoAuth userInfoAuth = this.getUserAuth(userId);
		StringBuilder authValue = new StringBuilder(userInfoAuth.getAuthValue());
		Map<Integer, Character> map = new HashMap<Integer, Character>();
		for (Integer key : authKeyList) {
			Character c = authValue.charAt(key - 1);
			map.put(key, c);
		}
		return map;
	}

	@Override
	public UserInfoAuth initAuth(String userId, int maxIndex) {
		UserInfoAuth userInfoAuth = new UserInfoAuth();
		userInfoAuth.setUserId(userId);

		userInfoAuth.setAuthValue(getDefaultString(maxIndex));

		try {
			userInfoAuthDao.save(userInfoAuth);
			return userInfoAuth;
		} catch (Exception e) {
			logger.error("userInfoAuthDao.save exception", e);
			return userInfoAuthDao.getUserAuth(userId);
		}
	}

	@Override
	@Transactional
	public void saveAuthByAuthValueList(String userId,
			List<AuthValue> authValueList) {
		TreeMap<Integer, Character> authMap = new TreeMap<Integer, Character>();
		for (AuthValue authValue : authValueList) {
			authMap.put(authValue.getName().getIndex(), authValue.getValue());
		}
		this.saveAuthByValueMap(userId, authMap);
	}

	@Override
	public Map<Integer, Character> getAuthByEnumList(String userId,
			List<UserAuthName> authNameList) {
		TreeSet<Integer> authKeyList = new TreeSet<Integer>();
		for (UserAuthName authName : authNameList) {
			authKeyList.add(authName.getIndex());
		}
		return this.getAuthNameKeyList(userId, authKeyList);
	}

	private String getDefaultString(int maxIndex) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < maxIndex; i++) {
			sb.append(defaultCharacter);
		}
		return sb.toString();
	}

	@Override
	public UserInfoAuth getUserAuth(String userId) {
		UserInfoAuth userInfoAuth = userInfoAuthDao.selectForUpdate(userId);
		if (userInfoAuth == null) {
			userInfoAuth = this.initAuth(userId, defaultMaxLength);
		}
		return userInfoAuth;
	}

	@Override
	public boolean authRealname(String uid, String realname, String idNum) {
		UserInfoAuth userInfoAuth = userInfoAuthDao.selectForUpdate(uid);
		if (userInfoAuth == null) {
			logger.info("Failed to get user auth by id[{}]", uid);
			return false;
		}
		// 调用外部接口进行实名认证
		boolean successed = true;

		if (successed) {
			String authValues = userInfoAuth.getAuthValue();
			int index = UserAuthName.AUTH_REALNAME.getIndex();
			authValues = authValues.substring(0, index) + "1"
					+ authValues.substring(index + 1);
			userInfoAuth.setAuthValue(authValues);
			userInfoAuthDao.save(userInfoAuth);
			return true;
		} else {
			logger.warn("Failed to validate user realname[{},{}]", realname,
					idNum);
		}
		return false;
	}

	@Override
	public boolean isCompletedAuthRealname(String uid) {
		UserInfoAuth userInfoAuth = userInfoAuthDao.query(uid);
		if (userInfoAuth == null) {
			return false;
		}
		String authValues = userInfoAuth.getAuthValue();
		int index = UserAuthName.AUTH_REALNAME.getIndex();
		char c = authValues.charAt(index - 1);
		return c == 1;
	}

}
